package org.amphiprion.descentv2assistant.dao.xml;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.amphiprion.descentv2assistant.App;
import org.amphiprion.descentv2assistant.ApplicationConstants;
import org.amphiprion.descentv2assistant.entity.Ability;
import org.amphiprion.descentv2assistant.entity.Lieutenant;
import org.amphiprion.descentv2assistant.entity.MonsterAttack;
import org.amphiprion.descentv2assistant.entity.MonsterCharacteristic;
import org.amphiprion.descentv2assistant.entity.Product;
import org.amphiprion.descentv2assistant.filter.IdFilter;
import org.amphiprion.descentv2assistant.util.PreferenceUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.os.Environment;
import android.util.Log;

public class LieutenantXmlDao extends AbstractXmlDao {
	private static LieutenantXmlDao instance;

	public static LieutenantXmlDao getInstance() {
		if (instance == null) {
			instance = new LieutenantXmlDao();
		}
		return instance;
	}

	public Lieutenant getLieutenant(String lieutenantId, int act) {
		List<Lieutenant> monsters = getLieutenants(null, lieutenantId, false);
		if (monsters.get(0).getAct() == act) {
			return monsters.get(0);
		} else {
			return monsters.get(1);
		}
	}

	public List<Lieutenant> getLieutenants() {
		return getLieutenants(null, null, false);
	}

	public List<Lieutenant> getLieutenants(IdFilter filter) {
		return getLieutenants(filter, null, false);
	}

	public List<Lieutenant> getLieutenants(IdFilter filter, boolean lightView) {
		return getLieutenants(filter, null, lightView);
	}

	private List<Lieutenant> getLieutenants(IdFilter filter, String lieutenantId, boolean lightView) {

		List<Lieutenant> result = new ArrayList<Lieutenant>();
		String lng = PreferenceUtil.getLanguage();
		InputStream is = null;
		try {
			File f = new File(Environment.getExternalStorageDirectory() + "/" + ApplicationConstants.DIRECTORY + "/lieutenants.xml");

			if (f.exists()) {
				is = new FileInputStream(f);
			}
			if (is == null) {
				is = App.class.getResourceAsStream("/lieutenants.xml");
			}

			DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
			builderFactory.setNamespaceAware(true);

			DocumentBuilder builder = builderFactory.newDocumentBuilder();
			Document document = builder.parse(is);

			NodeList list = document.getElementsByTagName("lieutenant");
			for (int i = 0; i < list.getLength(); i++) {
				Element lieutenantNode = (Element) list.item(i);
				String productId = lieutenantNode.getAttributes().getNamedItem("product").getNodeValue();
				String id = lieutenantNode.getAttributes().getNamedItem("id").getNodeValue();

				if (lieutenantId != null && !lieutenantId.equals(id)) {
					continue;
				}

				Product product = ProductXmlDao.getInstance().getProduct(productId);
				if (!product.isOwned()) {
					continue;
				}

				// NAME
				Element localizedNode = (Element) lieutenantNode.getElementsByTagName("name").item(0);
				String name = getLocalizedText(localizedNode, lng);

				// ACTS
				NodeList actsList = lieutenantNode.getElementsByTagName("act");
				for (int j = 0; j < actsList.getLength(); j++) {
					Element actNode = (Element) actsList.item(j);
					int act = getIntAttribute(actNode, "value", 1);

					if (filter != null && !filter.contains("" + act)) {
						continue;
					}

					Lieutenant lieutenant = new Lieutenant(id);
					lieutenant.setName(name);
					lieutenant.setAct(act);
					if (!lightView) {
						fillLieutenant(lieutenant, actNode);
					}
					lieutenant.setProduct(product);
					result.add(lieutenant);

				}
			}

			is.close();
			return result;
		} catch (Throwable e) {
			Log.e(ApplicationConstants.PACKAGE, "", e);
			if (is != null) {
				try {
					is.close();
				} catch (Throwable ex) {
				}
			}
			return null;
		}
	}

	private void fillLieutenant(Lieutenant lieutenant, Element actNode) {
		List<Ability> abilities = new ArrayList<Ability>();
		NodeList list = actNode.getElementsByTagName("ability");

		for (int i = 0; i < list.getLength(); i++) {
			Element abilityNode = (Element) list.item(i);
			String id = getAttribute(abilityNode, "id", "");
			String param = getAttribute(abilityNode, "param", "");

			Ability ability = AbilityXmlDao.getInstance().getAbility(id).parseAbility(param);
			ability.setFlash(getBooleanAttribute(abilityNode, "flash", false));
			ability.setAction(getBooleanAttribute(abilityNode, "action", false));

			abilities.add(ability);
		}
		lieutenant.setAbilities(abilities);

		list = actNode.getElementsByTagName("characteristic");
		for (int i = 0; i < list.getLength(); i++) {
			Element cNode = (Element) list.item(i);

			MonsterCharacteristic mc = new MonsterCharacteristic();
			mc.setSpeed(getIntAttribute(cNode, "speed", 0));
			mc.setHealth(getIntAttribute(cNode, "health", 0));
			mc.setDefense(getAttribute(cNode, "defense", ""));
			int nbHeroes = getIntAttribute(cNode, "heroes", 2);
			lieutenant.setCharacteristic(nbHeroes, mc);
		}

		Element aNode = (Element) actNode.getElementsByTagName("attack").item(0);
		MonsterAttack ma = new MonsterAttack();
		ma.setMelee(getBooleanAttribute(aNode, "melee", true));
		ma.setDice(getAttribute(aNode, "dice", ""));
		lieutenant.setAttack(ma);

		// Attributs
		Element attributeNode = (Element) actNode.getElementsByTagName("attribute").item(0);
		lieutenant.setMight(getIntAttribute(attributeNode, "might", 0));
		lieutenant.setKnowledge(getIntAttribute(attributeNode, "knowledge", 0));
		lieutenant.setWillpower(getIntAttribute(attributeNode, "willpower", 0));
		lieutenant.setAwareness(getIntAttribute(attributeNode, "awareness", 0));

	}

}
